#include "VSDLodTerrainSwitchNode.h"
#include "VSDLodTerrainNode.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSDLodTerrainSwitchNode,VSSwitchNode)
BEGIN_ADD_PROPERTY(VSDLodTerrainSwitchNode,VSSwitchNode)
REGISTER_PROPERTY(m_uiIndexXInTerrain,IndexXInTerrain,VSProperty::F_SAVE_LOAD_CLONE)
REGISTER_PROPERTY(m_uiIndexZInTerrain,IndexZInTerrain,VSProperty::F_SAVE_LOAD_CLONE)
END_ADD_PROPERTY
IMPLEMENT_INITIAL_BEGIN(VSDLodTerrainSwitchNode)
IMPLEMENT_INITIAL_END
VSDLodTerrainSwitchNode::VSDLodTerrainSwitchNode(unsigned int uiIndexXInTerrain,unsigned int uiIndexZInTerrain)
{
	m_uiIndexXInTerrain = uiIndexXInTerrain;
	m_uiIndexZInTerrain = uiIndexZInTerrain;
}
VSDLodTerrainSwitchNode::VSDLodTerrainSwitchNode()
{
	
}
VSDLodTerrainSwitchNode::~VSDLodTerrainSwitchNode()
{

}
void VSDLodTerrainSwitchNode::UpDateView(VSCuller & Culler,double dAppTime)
{
	VSSwitchNode::UpDateView(Culler,dAppTime);
	VSCamera * pCamera = Culler.GetCamera();
	if (!pCamera)
	{
		return;
	}
	if (Culler.GetCullerType() == VSCuller::CUT_MAIN)
	{
		VSDLodTerrainNode * pTerrainNode = DynamicCast<VSDLodTerrainNode>(m_pParent);
		if (!pTerrainNode)
		{
			return ;
		}
		VSTransform Tran = pTerrainNode->GetWorldTransform();
		VSVector3 Loc = pCamera->GetWorldTranslate() * Tran.GetCombineInverse();
		unsigned int uiLength = 1 << pTerrainNode->GetTesselationLevel();
		VSVector3 Pos;
		unsigned int uiIndenX = uiLength * m_uiIndexXInTerrain;
		unsigned int uiIndenZ = uiLength * m_uiIndexZInTerrain;
		Pos.x = 1.0f * uiIndenX + (uiLength >> 1);
		Pos.z = 1.0f * uiIndenZ + (uiLength >> 1);;
		Pos.y = pTerrainNode->GetHeight(uiIndenX,uiIndenZ);

		VSVector3 Length = Loc - Pos;
		VSREAL fSqrLen = Length.GetSqrLength();
		for (unsigned int i = 0 ; i < m_pChild.GetNum() ; i++)
		{
			m_uiActiveNode = i;
			if ( fSqrLen < (1 << i) * pTerrainNode->GetScale())
			{		
				break;
			}
		}
	}


}
unsigned int VSDLodTerrainSwitchNode::DiskUse()const
{
	unsigned int Used = VSSwitchNode::DiskUse();

	Used += sizeof(unsigned int *) * 2;
	return Used;
}
bool VSDLodTerrainSwitchNode::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSSwitchNode::Save(rStream,iSaveUse))
		return 0;






	if(!rStream.Write(&m_uiIndexXInTerrain,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiIndexZInTerrain,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	return 1;
}
bool VSDLodTerrainSwitchNode::Load(VSStream & rStream,unsigned int &iSaveUse)
{	
	if(!VSSwitchNode::Load(rStream,iSaveUse))
		return 0;



	if(!rStream.Read(&m_uiIndexXInTerrain,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Read(&m_uiIndexZInTerrain,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	return 1;
}

bool VSDLodTerrainSwitchNode::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSDLodTerrainSwitchNode* Temp = DynamicCast<VSDLodTerrainSwitchNode>(pObject); 
	if(!Temp)
		return 0;
	if(VSSwitchNode::Clone(pObject,uiType))
	{
		m_uiIndexXInTerrain = Temp->m_uiIndexXInTerrain;
		m_uiIndexZInTerrain = Temp->m_uiIndexZInTerrain;
		
		return 1;

	}
	else
	{
		return 0;
	}

}